/*
 * Copyright (c) 2010-2013 Ruben Chakhmakhchyan. All rights reserved.
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Eclipse Public License
 * Version 1.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://opensource.org/licenses/EPL-1.0 and read it before using this file.
 */

#pragma once

#include "npapi.h"
#include "npruntime.h"


// Helper class that can be used to map calls to the NPObject hooks into virtual methods on instances of classes that derive from this class.
class NPObjectAdapter : public NPObject
{
public:
	NPObjectAdapter( NPP npp ) 
		: m_npp( npp )
	  {
	  }

	virtual ~NPObjectAdapter() { }

	virtual void invalidate() { }
	virtual bool hasMethod( NPIdentifier name ) { return false; }
	virtual bool invoke( NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result ) { return false; }
	virtual bool invokeDefault( const NPVariant *args, uint32_t argCount, NPVariant *result ) { return false; }
	virtual bool hasProperty( NPIdentifier name ) { return false; }
	virtual bool getProperty( NPIdentifier name, NPVariant *result ) { return false; }
	virtual bool setProperty( NPIdentifier name, const NPVariant *value ) { return false; }
	virtual bool removeProperty( NPIdentifier name ) { return false; }
	virtual bool enumerate( NPIdentifier **identifier, uint32_t *count ) { return false; }
	virtual bool construct( const NPVariant *args, uint32_t argCount, NPVariant *result ) { return false; }

public:
	static void Deallocate( NPObject *npobj );
	static void Invalidate( NPObject *npobj );
	static bool HasMethod( NPObject *npobj, NPIdentifier name );
	static bool Invoke( NPObject *npobj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result );
	static bool InvokeDefault( NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result );
	static bool HasProperty( NPObject * npobj, NPIdentifier name );
	static bool GetProperty( NPObject *npobj, NPIdentifier name, NPVariant *result );
	static bool SetProperty( NPObject *npobj, NPIdentifier name, const NPVariant *value );
	static bool RemoveProperty( NPObject *npobj, NPIdentifier name );
	static bool Enumerate( NPObject *npobj, NPIdentifier **identifier, uint32_t *count );
	static bool Construct( NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result );

public: //protected:
	NPP m_npp;
};


#define DECLARE_NPOBJECT_CLASS_WITH_BASE( _class )									\
	static NPObject*																\
	Allocate##_class( NPP npp, NPClass *aClass ) { return new _class( npp ); }		\
	static NPClass s##_class##_NPClass = {											\
	NP_CLASS_STRUCT_VERSION_CTOR,													\
	Allocate##_class,																\
	NPObjectBase::Deallocate,														\
	NPObjectBase::Invalidate,														\
	NPObjectBase::HasMethod,														\
	NPObjectBase::Invoke,															\
	NPObjectBase::InvokeDefault,													\
	NPObjectBase::HasProperty,														\
	NPObjectBase::GetProperty,														\
	NPObjectBase::SetProperty,														\
	NPObjectBase::RemoveProperty,													\
	NPObjectBase::Enumerate,														\
	NPObjectBase::Construct															\
}

#define GET_NPOBJECT_CLASS(_class) &s##_class##_NPClass
